package com.fin.zw.intelligentbot.service;

import com.fin.zw.intelligentbot.entity.BaseEntity;
import com.fin.zw.intelligentbot.entity.CategoryLabel;
import com.fin.zw.intelligentbot.entity.Company;
import com.fin.zw.intelligentbot.entity.QCategoryLabel;
import com.fin.zw.intelligentbot.enums.SourceType;
import com.fin.zw.intelligentbot.model.session.SessionModel;
import com.fin.zw.intelligentbot.repository.CategoryLabelRepository;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.dsl.BooleanExpression;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

@Service("categoryService")
public class CategoryService {

    private final static Logger log = LoggerFactory.getLogger(CategoryService.class);

    @Autowired
    private CategoryLabelRepository categoryLabelRepository;

    @Autowired
    private CommonService commonService;

    public BooleanBuilder generateCondition(Object query,Object condition)
    {
        BooleanBuilder builder = new BooleanBuilder();
        try {
            Class cls = condition.getClass();
            Field[] fields = cls.getDeclaredFields();

            for (Field f :fields)
            {
                f.setAccessible(true);
                Object v = f.get(condition);
                if(f!=null&& v!=null &&StringUtils.isNotEmpty(v.toString()))
                {
                    Field cfield = query.getClass().getDeclaredField(f.getName());
                    Method ms[]  = cfield.getType().getMethods();
                    for (Method m :ms)
                    {
                        if(m.getName().contains("contains"))
                        {
                            Object fq =  cfield.get(query);
                            BooleanExpression be = (BooleanExpression) m.invoke(fq, v.toString());
                            builder.and(be);
                            break;
                        }
                    }

                }
            }
        }catch (Exception ex)
        {
            log.error(ex.getMessage());
            ex.printStackTrace();
            //todo记录错误日志
        }
        return builder;
    }

    /**
     * 获取企业信息（主要是供其他业务进行选择使用）
     * @param sessionModel
     * @return
     */
    public List<BaseEntity> fetch(SessionModel sessionModel,CategoryLabel condition){

        List<BaseEntity> baseList = new ArrayList<>();
        Company cop = commonService.getCompany(sessionModel);

        BooleanBuilder builder = getBooleanBuilder(condition, cop);
        Iterable<CategoryLabel> iterable = this.categoryLabelRepository.findAll(builder);
        baseList.addAll(IterableUtils.toList(iterable));
        return baseList;
    }


    private BooleanBuilder getBooleanBuilder(CategoryLabel condition, Company cop) {
        BooleanBuilder builder = new BooleanBuilder();
        if (StringUtils.isNotEmpty(condition.getId())) {
            builder.and(QCategoryLabel.categoryLabel.id.eq(condition.getId()));
        }
        if (StringUtils.isNotEmpty(condition.getCode())) {
            builder.and(QCategoryLabel.categoryLabel.code.eq(condition.getCode()));
        }
        if (StringUtils.isNotEmpty(condition.getName())) {
            builder.and(QCategoryLabel.categoryLabel.name.eq(condition.getName()));
        }
        if (StringUtils.isNotEmpty(condition.getSceneType())) {
            builder.and(QCategoryLabel.categoryLabel.sceneType.eq(condition.getSceneType()));
        }
        if (Objects.nonNull(cop)) {
            builder.and(QCategoryLabel.categoryLabel.companies.contains(cop));
        } else {
            builder.and(QCategoryLabel.categoryLabel.source.eq(SourceType.SAFEMANAGER));
        }
        return builder;
    }

    /**
     * 分业务查询客户标签
     *
     * @param sessionModel
     * @param condition
     * @param pageable
     * @return
     */
    public Page<BaseEntity> fetchPage(SessionModel sessionModel, CategoryLabel condition, Pageable pageable) {
        Company cop = commonService.getCompany(sessionModel);
        BooleanBuilder builder = new BooleanBuilder();
        QCategoryLabel qCategoryLabel = QCategoryLabel.categoryLabel;
        if (cop != null) {
            builder.and(qCategoryLabel.companies.contains(cop));
        } else {
            builder.and(qCategoryLabel.source.eq(SourceType.SAFEMANAGER));
        }
        if (StringUtils.isNotEmpty(condition.getName())) {
            builder.and(qCategoryLabel.name.contains(condition.getName()));
        }
        if (StringUtils.isNotEmpty(condition.getCode())) {
            builder.and(qCategoryLabel.code.eq(condition.getCode()));
        }
        if (StringUtils.isNotEmpty(condition.getSceneType())) {
            builder.and(qCategoryLabel.sceneType.eq(condition.getSceneType()));
        }
        Page<CategoryLabel> labelPage = this.categoryLabelRepository.findAll(builder, pageable);
        Page<BaseEntity> page = labelPage.map(categoryLabel -> {
            return categoryLabel;
        });
        return page;
    }

    public BaseEntity add(BaseEntity category, SessionModel sessionModel){
        CategoryLabel cl = new CategoryLabel();
        BeanUtils.copyProperties(category,cl);
        Iterator<CategoryLabel> iterator = categoryLabelRepository.findAll(QCategoryLabel.categoryLabel.code.eq(cl.getCode())).iterator();
        if (iterator.hasNext()) {
            throw new RuntimeException("该编号已经存在！");
        }
        cl.setId(null);
        cl.setCreaterId(sessionModel.getUserId());
        if (StringUtils.isEmpty(sessionModel.getCompanyId())) {//用户为超级管理员，前端传回来的就是当前使用的企业
            cl.setSource(SourceType.SAFEMANAGER);
        } else {//用户为普通用户，前端传回来的使用企业为空，此处需要补充使用企业为用户所属企业
            Company company = commonService.getCompany(sessionModel);
            Set<Company> cops = new HashSet<>();
            cops.add(company);
            cl.setCompanies(cops);
            cl.setSource(SourceType.COMPANY);
        }

        CategoryLabel saveCl = this.categoryLabelRepository.save(cl);
        return saveCl;
    }

    public void update(CategoryLabel category,SessionModel session){
        BooleanBuilder builder = new BooleanBuilder();
        QCategoryLabel qCategoryLabel = QCategoryLabel.categoryLabel;
        builder.and(qCategoryLabel.id.notIn(category.getId()));
        builder.and(qCategoryLabel.code.eq(category.getCode()));
        Iterator<CategoryLabel> iterator = categoryLabelRepository.findAll(builder).iterator();
        if (iterator.hasNext()) {
            throw new RuntimeException("该编号已经存在！");
        }
        Optional<CategoryLabel> optional = this.categoryLabelRepository.findById(category.getId());
        if(!optional.isPresent()){
            log.info("更新的客户对象不存在");
            throw new RuntimeException("更新的客户对象不存在");
        }
        CategoryLabel old = optional.get();
        BeanUtils.copyProperties(category,old,CategoryLabel.class);
        this.categoryLabelRepository.save(old);
    }

    public void delete(String id){
        this.categoryLabelRepository.deleteById(id);
    }
}
